// $Id: bool.hpp 2 2009-09-02 08:47:42Z joseph2002 $
/*
 * Copyright 2009 Joseph Wu
 * Distributed under the Boost Software License, Version 1.0.
 * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
 *
 * For more information, see http://xpcomplus.sourceforge.net
 */

#ifndef XPCOM_IMPL_BOOL_HPP
#define XPCOM_IMPL_BOOL_HPP

#include <xpcom/config.hpp>
#include <boost/noncopyable.hpp>
#include <xpcom/types.hpp>

#ifdef BOOST_HAS_ABI_HEADERS
#include BOOST_ABI_PREFIX
#endif

namespace xpcom {
namespace impl {

//
// XPCOM implementation argument translators.
// Note: The out/inout arguments must not be null.
//
// bool_in(bool_t) --> bool
// bool_out(bool_t*) --> bool&
// bool_inout(bool_t*) --> bool&
//

XPCOM_FORCEINLINE
bool bool_in(bool_t b)
{
    return b != false_;
}

class bool_out : boost::noncopyable
{
public:
    explicit bool_out(bool_t* b) :
        b_(b), val_(false)
    {
    }

    ~bool_out()
    {
        *b_ = val_ ? true_ : false_;
    }

    XPCOM_FORCEINLINE
    operator bool&()
    {
        return val_;
    }

    XPCOM_FORCEINLINE
    void operator=(bool retval)
    {
        val_ = retval;
    }

private:
    bool_t* b_;
    bool val_;
};

class bool_inout : boost::noncopyable
{
public:
    explicit bool_inout(bool_t* b) :
        b_(b), val_(*b != false_)
    {
    }

    ~bool_inout()
    {
        *b_ = val_ ? true_ : false_;
    }

    XPCOM_FORCEINLINE
    operator bool&()
    {
        return val_;
    }

private:
    bool_t* b_;
    bool val_;
};

} // namespace xpcom::impl
} // namespace xpcom

#ifdef BOOST_HAS_ABI_HEADERS
#include BOOST_ABI_SUFFIX
#endif

#endif // XPCOM_IMPL_BOOL_HPP
